
#include "StdAfx.h"
#include "RoomManager.h"
#include "Room.h"
#include "User.h"
#include "LobbyService.h"
#include "UserManager.h"
#include "board_define.h"
#include <LogService.h>

RoomManager::RoomManager(){	
	create_lock_ = 1;
	delete_rooms_.reserve( DEF_DELETE_MAX_ROOM );
}

RoomManager::~RoomManager(){
}

void RoomManager::initialize( size_t max_room ){
	ident_generator_.initialize( UniqNumGenerater::DEF_MODE_JAM, 1, \
		max_room );

	if( LobbyService::Instance()->isRoomModeNormal() )
		return;

	Room* room = 0;
	for( size_t i = 0 ; i < max_room ; i++ ){
		room = create( 0, 0 );
		add( room );
	}
}

size_t RoomManager::size(){
	return rooms_.size();
}

int RoomManager::create_available(){
	return create_lock_;
}

void RoomManager::set_create_available( int value ){
	create_lock_ = value;
}

int RoomManager::add( Room* room ){
	size_t ident = ident_generator_.get();
	if(! ident ){
		LOG_ERR( LOG_SERVICE( "instance" )->Log("%s - %u", __FUNCTION__, __LINE__) );
		return DEF_ERROR_INTERNAL;
	}

	room->setIdent( ident );	
	
	if(! rooms_.add( ident, room ) ){
		LOG_ERR( LOG_SERVICE( "instance" )->Log("%s - %u", __FUNCTION__, __LINE__) );
		return DEF_ERROR_INTERNAL;
	}

	return DEFAULT_SUCCESS;
}

int RoomManager::remove( size_t idx ){
	ident_generator_.free( idx );
	
	if(! rooms_.remove( idx ) ){
		LOG_ERR( LOG_SERVICE( "instance" )->Log("%s - %u", __FUNCTION__, __LINE__) );
		return DEF_ERROR_INTERNAL;
	}
	
	return DEF_ERROR_INTERNAL;
}

Room* RoomManager::get( size_t idx ){	
	return rooms_.get( idx );		
}

void RoomManager::add_delete_room( Room* room ){
	if(! LobbyService::Instance()->isRoomModeNormal() )
		return;

	delete_rooms_.push_back( room );
}

void RoomManager::process_check_dummy_user(){	
	/*
	Room* room = 0;
	rooms_.resetCursor();

	while(! rooms_.isEnd() ){
		room = rooms_.getCurrentValue();
		IS_NULL_ACTION( room, break );

		if( room->isDeleteReserve() ){
			rooms_.nextCursor();
			continue;
		}

		room->
		
		rooms_.nextCursor();
	}
	*/
}

int RoomManager::process_delete_rooms(){
	int count = 0;
	Room* room = 0;
	size_t i = 0;

	for( i = 0 ; i < delete_rooms_.size() ; i++ ){
		room = delete_rooms_[ i ];
		IS_NULL_ACTION( room, continue );

		if( LobbyService::Instance()->isRoomModeNormal() ){
			room->force_exit_observers();
			remove( room->getIdent() );
		}

		destroy( room );

		count++;
	}

	delete_rooms_.clear();	

	return count;
}

int RoomManager::sendRoomList( User* user ){
	int send_size = 0;
	int send_count = 0;
	char buffer[ LobbyService::DEF_MAX_SEND_BUFFER ];
	memset( buffer, 0, LobbyService::DEF_MAX_SEND_BUFFER );	
	Room* room = 0;
	
	send_size = makeRoomList( LobbyService::DEF_MAKE_TYPE_START, 0, buffer, \
		LobbyService::DEF_MAX_SEND_BUFFER );
	if( send_size )
		user->send( buffer, send_size );
	
	int iCount = 0;
	rooms_.resetCursor();
	while(! rooms_.isEnd() ){
		room = rooms_.getCurrentValue();
		IS_NULL_ACTION( room, break );

		if( room->isDeleteReserve() ){
			rooms_.nextCursor();
			continue;
		}

		send_size = makeRoomList( LobbyService::DEF_MAKE_TYPE_BODY, room, buffer, LobbyService::DEF_MAX_SEND_BUFFER );
		if( send_size )
			user->send( buffer, send_size );

		iCount++;
		send_count++;
		rooms_.nextCursor();
	}	

	send_size = makeRoomList( LobbyService::DEF_MAKE_TYPE_END, 0, buffer, LobbyService::DEF_MAX_SEND_BUFFER );
	if( send_size )
		user->send( buffer, send_size );	

	return send_count;
}

Room* RoomManager::getEnterAvailableRoom( User* user ){
	size_t room_idx = 0;
	Room* room = 0;
	
	rooms_.resetCursor();

	while(! rooms_.isEnd() ){
		room_idx = 0;
		room = rooms_.getCurrentValue();
		IS_NULL_ACTION( room, break );

		if( room->getPasswd() ){
			rooms_.nextCursor();
			continue;
		}

		if( room->enterCheck( user ) ){
			rooms_.nextCursor();
			continue;
		}

		return room;		
	}	

	return 0;
}

int RoomManager::broadcast( char* data, size_t size ){
	IS_NULL_RETURN( data, 0 );
	IS_NULL_RETURN( size, 0 );

	size_t send_count = 0;
	Room* room = 0;
	
	rooms_.resetCursor();

	while(! rooms_.isEnd() ){
		room = rooms_.getCurrentValue();
		IS_NULL_ACTION( room, break );
		
		room->broadcast( data, size );
		send_count++;
		rooms_.nextCursor();
	}	

	return send_count;
}

int RoomManager::broadcast_except( char* data, size_t size, size_t ident ){
	IS_NULL_RETURN( data, 0 );
	IS_NULL_RETURN( size, 0 );

	size_t send_count = 0;
	Room* room = 0;
	
	rooms_.resetCursor();

	while(! rooms_.isEnd() ){
		room = rooms_.getCurrentValue();
		IS_NULL_ACTION( room, break );

		if( room->getIdent() == ident ){
			rooms_.nextCursor();
			continue;
		}
		
		room->broadcast( data, size );
		send_count++;
		rooms_.nextCursor();
	}	

	return send_count;
}
